#include <amqp.h>
#include "head.h"
#include "config.h"
#include <rabbitmq_api.h>

struct Config config;

int main(int argc, char ** argv) {
    int opt;
    pid_t pid;
    int qid;
    char configPath[128] = {0};
    int nwork = 0, masterPort = 0;
    char masterIp[20] = {0};
    init_config(&config); // 实现缺省值

    while ((opt = getopt(argc, argv, "o:n:m:p:")) != -1) {
        switch (opt) {
            case 'o':
                strcpy(configPath, optarg);
                break;
            case 'n':
                // config.nworker = atoi(optarg);
                nwork = atoi(optarg);
                break;
            case 'm':
                // strcpy(config.masterIp, optarg);
                strcpy(masterIp, optarg);
                break;
            case 'p':
                // config.masterPort = atoi(optarg);
                masterPort = atoi(optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -o configPath-n nwork -m masterip -p masterPort\n", argv[0]);
                exit(1);
        }
    }    
    
    if (configPath[0] == '\0') {
        strcpy(configPath, "/etc/slaveHealth/slave.json");
    }
    char pwdBuff[128] = {0};
    getcwd(pwdBuff, sizeof(pwdBuff));
    // DBG("<"YELLOW"DEBUG"NONE"> : cwd: %s", pwdBuff);
    // DBG("<"YELLOW"DEBUG"NONE"> : configPath: %s", configPath);

    if (get_config(configPath, &config) < 0) {
        perror("get_config");
        exit(1);
    }
    
    if (config.masterIp[0] == '\0' || config.masterPort == 0) {
        fprintf(stderr, "MasterIp or MasterPort is empty\n");
        exit(1);
    }
    // DBG("<"YELLOW"Debug"NONE"> : MasterIp = %s", config.masterIp);
    // DBG("<"YELLOW"Debug"NONE"> : MasterPort = %d", config.masterPort);
    // DBG("<"YELLOW"Debug"NONE"> : cpu's time = %d", config.interTime.cpu.time);
    // DBG("<"L_GREEN"Note"NONE"> : Finish with config...");

    key_t key = ftok(".", 202103);

    if ((qid = create_queue(key)) < 0) {
        perror("create_queue");
        exit(1);
    }
    // DBG("<"L_GREEN"Note"NONE"> : Msg queue created...");

    if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }
    
    if (pid) {
        // DBG("<"L_GREEN"Note"NONE"> : In Father Process");
        send_loop(qid, &config);
        while (1) {
            sleep(100000);
        }
    } else {
        // DBG("<"L_GREEN"Note"NONE"> : Child Process created for system detect...");
        // pthread_create => nworker
        // system & popen 执行脚本
        struct threadpool_t *pool = NULL;
        if ((pool = (struct threadpool_t *)malloc(sizeof(struct threadpool_t))) == NULL)
        {
            fprintf(stderr, "malloc threadpool false\n");
            exit(1);
        }
        pool->qid = qid;
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
        pthread_mutex_init(&(pool->lock), &attr);

        pthread_mutexattr_t rabbit_attr;
        pthread_mutexattr_init(&rabbit_attr);
        pthread_mutexattr_setpshared(&rabbit_attr, PTHREAD_PROCESS_SHARED);
        pthread_mutex_init(&(pool->rabbit_lock), &rabbit_attr);

        amqp_connection_state_t conn = NULL;
        if((conn = connectServer(config.rabbitCon.RabbitMQIp, config.rabbitCon.RabbitMQPort)) == NULL) {
            exit(1);
        }
        pool->conn = conn;

        pthread_t tid[config.nworker];
        for (int i = 0; i < config.nworker; i++) {
            // DBG("<"L_GREEN"Note"NONE"> : In Child Process, Creating thread No.%d", i + 1);
            pool->channel = i + 1;
            amqp_channel_open(conn, i + 1);
            amqp_rpc_reply_t replyRes = amqp_get_rpc_reply(conn);
            if (replyRes.reply_type != AMQP_RESPONSE_NORMAL) {
                DBG("<"RED"ERROR"NONE"> open channel failed, exit!");
                exit(1);
            }
            pthread_create(&tid[i], NULL, thread_recv_msg, (void *)pool);
        }
        while (1) {
            sleep(10000);
        }
    }

    return 0;
}